<template>
  <div class="WidgetWrapper" :style="style">
    <component
      ref="componentInstance"
      :is="component"
      :widgetConfig="widgetConfig"
      :getComponent="getComponent"
    ></component>
  </div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Ref, Inject, Watch } from 'vue-property-decorator'
import { addListener, removeListener } from 'resize-detector'
import WidgetConfig from '@/core/model/WidgetConfig'
import Widget from '../widget/invisible/DefaultWidget.vue'
import ApplicationEditor from '@/components/application-editor/ApplicationEditor.vue'
import WidgetRuntimeConfig from '@/core/model/WidgetRuntimeConfig'
// import WidgetGroup from './WidgetGroup.vue'

@Component
export default class WidgetWrapper extends Vue {
  @Inject('app-editor')
  public appEditor!: ApplicationEditor

  @Prop()
  public widgetConfig!: WidgetConfig

  @Prop()
  public getComponent!: (tag: string) => Vue.Component

  @Ref()
  public componentInstance!: Vue

  private clientWidth = -1

  private clientHeight = -1
  private _runtime!: WidgetRuntimeConfig

  private get widgetDefinition() {
    return this.appEditor.getWidgetDefinitionBytag(this.widgetConfig._widgetTag)
  }

  private get autoSize() {
    return this.widgetDefinition?.autoSize || false
  }

  get style () {
    const autoSize = this.autoSize
    const widgetConfig = this.widgetConfig
    const baseConfig = this.widgetConfig.base
    const width = Math.round(autoSize ? widgetConfig._runtime.w : widgetConfig.base.w)
    const height = Math.round(autoSize ? widgetConfig._runtime.h : widgetConfig.base.h)
    const left = Math.round(widgetConfig.base.x)
    const top = Math.round(widgetConfig.base.y)

    const style = {
      width: autoSize? 'auto' : (width + 'px'),
      height: autoSize? 'auto' : (height + 'px'),
      left: left + 'px',
      top: top + 'px',
      marginLeft: '',
      marginTop: '',
    }

    if (baseConfig.anchor === 'right-top') {
      style.marginLeft = `-${width}px`
    }

    if (baseConfig.anchor === 'center') {
      style.marginLeft = `-${width / 2}px`
      style.marginTop = `-${height / 2}px`
    }

    if (baseConfig.anchor === 'left-bottom') {
      style.marginTop = `-${height}px`
    }

    if (baseConfig.anchor === 'right-bottom') {
      style.marginLeft = `-${width}px`
      style.marginTop = `-${height}px`
    }

    if (baseConfig.anchor === 'center-top') {
      style.marginLeft = `-${width / 2}px`
    }

    if (baseConfig.anchor === 'center-bottom') {
      style.marginLeft = `-${width / 2}px`
      style.marginTop = `-${height}px`
    }

    if (baseConfig.anchor === 'left-center') {
      style.marginTop = `-${height / 2}px`
    }

    if (baseConfig.anchor === 'right-center') {
      style.marginLeft = `-${width}px`
      style.marginTop = `-${height / 2}px`
    }

    return style
  }

  private get component() {
    if (this.widgetConfig) {
      return this.getComponent(this.widgetConfig._widgetTag)
    }
    return Widget
  }

  private resizeHandler() {
    const $el = this.componentInstance.$el
    const width = $el.clientWidth
    const height = $el.clientHeight
    this.clientWidth = width
    this.clientHeight = height
    this.widgetConfig._runtime.w = width
    this.widgetConfig._runtime.h = height
  }

  @Watch('widgetConfig')
  private handleWidgetConfigChange() {
    this.widgetConfig._runtime = this._runtime
  }

  private async mounted () {
    this._runtime = this.widgetConfig._runtime
    this.resizeHandler()
    addListener(this.$el as HTMLElement, this.resizeHandler)
  }

  private beforeDestroy () {
    removeListener(this.$el as HTMLElement, this.resizeHandler)
  }
}
</script>
<style scoped lang="scss">
@import '~@/style/variables.scss';
.WidgetWrapper {
  position: absolute;
}
</style>
